import random
import datetime
import hashlib
from common.read_yaml import ReadYamlData
import string
from dateutil import parser


class DebugTalk(object):
    def __init__(self):
        self.read = ReadYamlData()

    def mode_exist(self, data, mode=None):
        """
        处理数据
        :param data:
        :param mode:数据处理模式 0:随机选择一个值 -1:转为逗号拼接字符串 -2:转为字符串列表
        :return:
        """
        mode = int(mode)
        data_value = {
            mode: data[mode - 1],
            0: random.choice(data),
            -1: ','.join(map(str, data)),
            -2: ','.join(map(str, data)).split(',')
        }
        return data_value[mode]

    def get_extract_data(self, key, mode=None, *sub_keys):

        data = self.read.get_extract_yaml(key, *sub_keys)

        if mode is not None:
            data = self.mode_exist(data, mode)

        return data

    def md5_params(self, params):
        """
        对输入参数进行MD5加密处理

        :param params: 需要进行MD5加密的字符串参数
        :return: 参数的MD5加密结果，以十六进制字符串形式返回
        """
        enc_data = hashlib.md5()
        enc_data.update(params.encode(encoding="utf-8"))
        return enc_data.hexdigest()

    def generate_random_number(self, length, char_type='number'):
        """
        生成指定位数的随机字符串

        :param length: 随机字符串位数
        :param char_type: 字符类型
            - 'number': 只包含数字 (0-9) - 保持向后兼容
            - 'lower': 只包含小写字母 (a-z)
            - 'upper': 只包含大写字母 (A-Z)
            - 'letter': 只包含字母 (a-z, A-Z)
            - 'alphanumeric': 包含字母和数字 (a-z, A-Z, 0-9)
        :return: 指定位数的随机字符串
        """
        if not isinstance(length, int):
            length = int(length)
        char_sets = {
            'number': string.digits,
            'lower': string.ascii_lowercase,
            'upper': string.ascii_uppercase,
            'letter': string.ascii_letters,
            'alphanumeric': string.ascii_letters + string.digits
        }

        chars = char_sets.get(char_type, string.digits)  # 默认为数字
        return ''.join(random.choice(chars) for _ in range(length))

    def get_date(self, time_unit=None, offset_value=0, date_str=None):
        """
        获取日期时间字符串，支持简单时间偏移
        :param time_unit: 时间单位
                          可选值: 'years', 'months', 'days', 'hours', 'minutes', 'seconds'
        :param offset_value: 偏移数值，正数表示未来，负数表示过去
        :param date_str: 指定的基础日期时间字符串
                       如果为None，则使用当前时间
        :return: 格式化后的日期时间字符串 'YYYY-MM-DD HH:MM:SS'
        """
        if not isinstance(offset_value, int):
            offset_value = int(offset_value)
        if date_str is not None:
            base_time = parser.parse(date_str)
        else:
            base_time = datetime.datetime.now()
        if time_unit is None or offset_value == 0:
            return base_time.strftime('%Y-%m-%d %H:%M:%S')
        # 获取偏移参数
        years = offset_value if time_unit == 'years' else 0
        months = offset_value if time_unit == 'months' else 0
        days = offset_value if time_unit == 'days' else 0
        hours = offset_value if time_unit == 'hours' else 0
        minutes = offset_value if time_unit == 'minutes' else 0
        seconds = offset_value if time_unit == 'seconds' else 0

        if years != 0 or months != 0:
            new_month = base_time.month + months
            new_year = base_time.year + years + (new_month - 1) // 12
            new_month = (new_month - 1) % 12 + 1
            try:
                base_time = base_time.replace(year=new_year, month=new_month)
            except ValueError:
                # 如果日期无效（如2月30日），则调整到该月最后一天
                if new_month == 12:
                    base_time = base_time.replace(year=new_year, month=12, day=31)
                else:
                    # 获取下个月第一天，然后减去一天得到该月最后一天
                    next_month = base_time.replace(year=new_year, month=new_month + 1, day=1)
                    base_time = next_month - datetime.timedelta(days=1)
        # 根据传入的参数计算偏移后的时间
        offset_time = base_time + datetime.timedelta(
            days=days,
            hours=hours,
            minutes=minutes,
            seconds=seconds
        )

        # 将计算后的时间格式化为字符串并返回
        return offset_time.strftime('%Y-%m-%d %H:%M:%S')


if __name__ == '__main__':
    debug = DebugTalk()
    # 测试用例
    print("当前时间:", debug.get_date())
    print("20230801231105加1年:", debug.get_date( 'years', 1))
